package rain;

import java.util.*;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.dao.*;
import java.sql.*;
import javax.sql.*;


/**
 *  DAO implementation built using Spring JDBCTemplate
 *
 *  @author 517 Development Team
 */


public class SpringJdbcTemplateVideoDao extends JdbcDaoSupport implements
		VideoDao {

	private static String SQL_VIDEO_QUERY = "select * from video_recordings where category = ?";
	private static String SQL_SINGLE_VIDEO_QUERY = "Select * from video_recordings where recording_id=?";

	
	/**
	 * 
	 * Class providing callback for selecting video recordings
	 *
	 */
	
	class VideoCategoryQuery extends MappingSqlQuery{
		
		public VideoCategoryQuery(DataSource ds){
			super(ds, "Select * from video_categories");
			compile();
		}

	/**
	 * Abstract method - maps ResultSet row to category
	 */	
		public Object mapRow(ResultSet rs, int rowNumber)throws SQLException{
			return rs.getString("name");
			
		}
	}
	
	
	public List<String> getVideoCategories() throws DaoException {
		VideoCategoryQuery videoCategoryQuery = new VideoCategoryQuery(getDataSource());
		return videoCategoryQuery.execute();
		
	}

	
	/**
	 * Helper method for building VideoRecording from ResultSet
	 */
	
	private VideoRecording buildResultSetRecording(ResultSet rs) throws SQLException{
		VideoRecording recording = new VideoRecording();
		recording.setId(rs.getInt("recording_id"));
		recording.setDirector(rs.getString("director"));
		recording.setTitle(rs.getString("title"));
		recording.setCategory(rs.getString("category"));
		recording.setImageName(rs.getString("image_name"));

		recording.setDuration(new Duration(rs.getInt("duration")));

		recording.setRating(rs.getString("rating"));
		recording.setYearReleased(rs.getInt("year_released"));
		recording.setPrice(rs.getDouble("price"));
		recording.setStockCount(rs.getInt("stock_count"));

		recording.setActors(null);
		return recording;
	}
	
	
	/**
	 * 
	 * Class providing callback for selecting video recordings
	 * for a given category
	 */
	
	class VideoRecordingQuery extends MappingSqlQuery{
		
		public VideoRecordingQuery(DataSource ds, String query){
			super(ds, query);
		    super.declareParameter(new SqlParameter(Types.VARCHAR));
			compile();
		}

	/**
	 * Abstract method - maps ResultSet row to VideoRecording object
	 */	
		public Object mapRow(ResultSet rs, int rowNumber)throws SQLException{
			return buildResultSetRecording(rs);
		}
	}
	
	
	
	public List<VideoRecording> getVideoRecordings(String theCategory)throws DaoException{
		return getVideoRecordings(theCategory, VideoDao.SORT_BY_TITLE);
	}

	
	public List<VideoRecording> getVideoRecordings(String theCategory,
			int sortBy) throws DaoException {
		String orderString = null;
		switch(sortBy){
		case VideoDao.SORT_BY_PRICE:
			orderString = " order by price";
			break;
		case VideoDao.SORT_BY_STOCK_COUNT:
			orderString = " order by stock_count";
			break;
		default:
			orderString = " order by title";
		}
		VideoRecordingQuery videoRecordingQuery = new VideoRecordingQuery(getDataSource(),
				SQL_VIDEO_QUERY + orderString);
		List videoList = videoRecordingQuery.execute(theCategory);
		return videoList;
	}

	
		/**
		 * 
		 * Class providing callback for selecting video recordings
		 * for a given category
		 */
		
		class SingleVideoRecordingQuery extends MappingSqlQuery{
			
			public SingleVideoRecordingQuery(DataSource ds, String query){
				super(ds, query);
				super.declareParameter(new SqlParameter(Types.INTEGER));
				compile();
			}

		/**
		 * Abstract method - maps ResultSet row to VideoRecording object
		 */	
			public Object mapRow(ResultSet rs, int rowNumber)throws SQLException{
				return buildResultSetRecording(rs);
			}
		}
		
	
	
	
	public VideoRecording getVideoRecording(String recordingId)
			throws DaoException {
		return this.getVideoRecording(Integer.parseInt(recordingId));
	}

	public VideoRecording getVideoRecording(int recordingId)
			throws DaoException {

		SingleVideoRecordingQuery query = new SingleVideoRecordingQuery(getDataSource(),
						SQL_SINGLE_VIDEO_QUERY);
		return (VideoRecording)query.findObject(recordingId);
		

	}


}
